﻿using System;
using HK.Core.Common.Data;
using HK.Core.Common.Protocol.Data;
using HK.Core.Pool.Protocol;

namespace HK.Core.Load.Protocol.Signal
{

    /// <summary>
    /// 通知信号群组
    /// </summary>
    [Flags]
    public enum NotifySignalGroup
    {
        /// <summary>
        /// Entity
        /// </summary>
        Entity = 0x00000001,
        
        /// <summary>
        /// Asset
        /// </summary>
        Asset = 0x00000002,
        
        /// <summary>
        /// AssetBundle
        /// </summary>
        AssetBundle = 0x00000004,
        
        /// <summary>
        /// LoadPool
        /// </summary>
        LoadPool = 0x00000008,
        
        /// <summary>
        /// 未知群组
        /// </summary>
        Unknown = 0x00000010,
        
        /// <summary>
        /// All
        /// </summary>
        All = Entity | Asset | AssetBundle
    }
    
    /// <summary>
    /// 通知信号类型
    /// </summary>
    [Flags]
    public enum NotifySignalType
    {
        /// <summary>
        /// Use - Entity
        /// </summary>
        EntityUse = 0x00000001,
        /// <summary>
        /// Use - Asset
        /// </summary>
        AssetUse = 0x00000002,
        /// <summary>
        /// Use - Ab
        /// </summary>
        AssetBundleUse = 0x00000004,
        
        /// <summary>
        /// 通知Use信号 - Entity
        /// <para>Asset+AssetBundle</para>
        /// </summary>
        NotifyEntityUse = AssetUse | AssetBundleUse,
        
        /// <summary>
        /// 通知加载信号 - Asset
        /// <para>AssetBundle</para>
        /// </summary>
        NotifyAssetUse = AssetBundleUse,
        
        /// <summary>
        /// UnUse - Entity
        /// </summary>
        EntityUnUse = 0x00000008,
        /// <summary>
        /// UnUse - Asset
        /// </summary>
        AssetUnUse = 0x00000010,
        /// <summary>
        /// UnUse - Ab
        /// </summary>
        AssetBundleUnUse = 0x00000020,
            
        /// <summary>
        /// 通知UnUse信号 - Entity
        /// <para>Asset+AssetBundle</para>
        /// </summary>
        NotifyEntityUnUse = AssetUnUse | AssetBundleUnUse,
        
        /// <summary>
        /// 通知UnUse信号 - Asset
        /// <para>AssetBundle</para>
        /// </summary>
        NotifyAssetUnUse = AssetBundleUnUse,
            
        /// <summary>
        /// 移除 - Entity
        /// </summary>
        EntityRemove = 0x00000040,
        /// <summary>
        /// 移除 - Asset
        /// </summary>
        AssetRemove = 0x00000080,
        /// <summary>
        /// 移除 - Ab
        /// </summary>
        AssetBundleRemove = 0x00000100
    }
    
    /// <summary>
    /// 接口 : 通知信号
    /// </summary>
    public interface INotifySignal : IPoolElement
    {
        /// <summary>
        /// 信号Key
        /// <para>* 唯一表示Key</para>
        /// </summary>
        string Key { get; }
        
        /// <summary>
        /// 已被使用
        /// </summary>
        bool Used { get; }

        /// <summary>
        /// 使用
        /// <para>* 一旦信号被人捡起，请调用该函数，以便标记当前信号被使用，在下一个循环回收时，会从队列中移除该信号</para>
        /// </summary>
        void Use();
        
        /// <summary>
        /// 信号数据
        /// </summary>
        IJsonData Data { get; }

        /// <summary>
        /// 设定信息
        /// </summary>
        /// <param name="iKey">Key</param>
        /// <param name="iData">信号数据</param>
        void SetInfo(string iKey, IJsonData iData = null);
    }
    
    /// <summary>
    /// 事件委托定义 : 群组通知事件
    /// <param name="iSignal">信号类型</param>
    /// <param name="iKey">信号Key</param>
    /// <param name="iSignalData">信号内容</param>
    /// </summary>
    public delegate void SignalNotify(int iSignal, string iKey, IJsonData iSignalData = null);

    /// <summary>
    /// 接口 : 信号订阅
    /// </summary>
    public interface ISignalSubscribe
    {
        /// <summary>
        /// 信号订阅事件
        /// </summary>
        event SignalNotify Subscribe;

        /// <summary>
        /// 信号通知时间
        /// </summary>
        /// <param name="iSignal">信号</param>
        /// <param name="iKey">Key</param>
        /// <param name="iData">信号数据</param>
        void Notify(int iSignal, string iKey, IJsonData iData = null);
    }

    /// <summary>
    /// 接口 : 信号流水线
    /// </summary>
    public interface ISignalPipe
    {
        /// <summary>
        /// 推送信号
        /// </summary>
        /// <param name="iGroup">信号群组</param>
        /// <param name="iSignal">信号</param>
        /// <param name="iKey">信号Key</param>
        void PushSignal(int iGroup, int iSignal, string iKey);
        
        /// <summary>
        /// 推送信号
        /// </summary>
        /// <param name="iGroup">信号群组</param>
        /// <param name="iSignal">信号</param>
        /// <param name="iKey">信号Key</param>
        /// <param name="iSignalData">信号数据</param>
        void PushSignal<TSignal>(int iGroup, int iSignal, string iKey, TSignal iSignalData) where TSignal : JsonData;
        
        /// <summary>
        /// 刷新信号管线
        /// <para>* 清除已使用的信号，以及无效信号</para>
        /// </summary>
        void Refresh();

    }

}